/*
 *  armboot - Startup Code for S3C6400/ARM1176 CPU-core
 *
 *  Copyright (c) 2007	Samsung Electronics
 *
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 */
#include <s5pc100.h>
/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */

.globl _start
_start: b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq

_undefined_instruction:
	.word undefined_instruction
_software_interrupt:
	.word software_interrupt
_prefetch_abort:
	.word prefetch_abort
_data_abort:
	.word data_abort
_not_used:
	.word not_used
_irq:
	.word irq
_fiq:
	.word fiq
_pad:
	.word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:

	.balignl 16,0xdeadbeef
/*
 *************************************************************************
 *
 * Startup Code (reset vector)
 *
 * do important init only if we don't start from memory!
 * setup Memory and board specific bits prior to relocation.
 * relocate armboot to ram
 * setup stack
 *
 *************************************************************************
 */
reset:
/*
 * cpu 모드를 SVC32 모드로 설정하고 IRQ & FIQ 를 disable 한다.
 *
 * 10000 - user
 * 10001 - FIQ
 * 10010 - IRQ
 * 10011 - SVC
 * 10111 - Abort
 * 11011 - Undefined
 * 11111 - System
 */
    mrs r0,cpsr         @ cpsr 값을 r0 로 가져옴.
    bic r0,r0,#0x1f     @ 하위 5비트 0으로 초기화.
    orr r0,r0,#0xd3     @ svc 모드, fiq,irq disable
    msr cpsr,r0         @ cpsr 에 적용.

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
     /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
cpu_init_crit:
   /*
    * Invalidate L1 I/D
    */
    mov	r0, #0                  @ set up for MCR
    mcr	p15, 0, r0, c8, c7, 0   @ invalidate TLBs
    mcr	p15, 0, r0, c7, c5, 0   @ invalidate icache

   /*
    * disable MMU stuff and caches
    */
    mrc	p15, 0, r0, c1, c0, 0
    bic	r0, r0, #0x00002000     @ clear bits 13 (--V-)   - Low Vector Address 사용 0x0000000
    bic	r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)  - Dcache , Alignment fault , MMU disable
    orr	r0, r0, #0x00000002     @ set bit 1 (--A-) Align - Alignment falut enable
    orr	r0, r0, #0x00000800     @ set bit 12 (Z---) BTB  - 주석이 잘못 된듯 싶음. 12번째 비트는 Icache 고 11번째 비트가 BTB 임.
    mcr 	p15, 0, r0, c1, c0, 0

    /* Read booting information (s5pc100 에 특화되었음. 일반적으로 필요 없다.) 
     * S5PC100 데이터 시트 참조 
     * SFR(special function register) map 에 나와있음
     * IROM_CODE 내에 보면 register description 이 잘 되있음.
     * PRO_ID_BASE = 0xE0000000
     * ==========================================================================================
     * PRODUCT_ID_REGISTER = [31:12] - 프로덕트 ID 값이 들어있음 S5PC100 은 0x43100 설정됨.
     *                       [7:4]   - Main revision Number
     *                       [3:0]   - Sub revision Number
     * ==========================================================================================

     * ==========================================================================================
     *OPERATING_MODE_REGISTER = [4:0] - 부팅 모드 정보가 들어있음
     *                            [4]   - 0 = normal mode , 1 = test mode
     *                            [3]   - 1 = 1st boot loader in iROM , 1 = reserved
     *                            [2:1]   2nd boot loader 정보  - 00 = NAND
     *                                                            01 = OneNAND
     *                                                            02 = MMC
     *                                                            03 = Reserved
     * ==========================================================================================
     */

    ldr	r0, =PRO_ID_BASE
    ldr	r1, =OMR_BASE
    bic	r2, r1, #0xfffffff9
    cmp	r2, #0x0
    moveq	r3, #BOOT_NAND
    cmp	r2, #0x2
    moveq	r3, #BOOT_ONENAND
    cmp      r2, #0x4
    moveq    r3, #BOOT_MMCSD	

    /* INFORMATION 0~3 은 XnRESET(외부 하드웨어 신호) 에 
     * 의해 클리어되는 Information register 이다. 
     * 리셋되었을경우 부팅 방법에 따라 처리하기 위해 저장해 놓음
     */
    ldr r0, =INF_REG_BASE
    str r3, [r0,#INF_REG3_OFFSET]

    bl lowlevel_init
    
undefined_instruction:
software_interrupt:
prefetch_abort:
data_abort:
not_used:
irq:
fiq:

